#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <stdbool.h>
#include <time.h>
//非阻塞显示
#include <termios.h>
#include <errno.h>
#include <fcntl.h>


//复合计算器
#include <ctype.h>
#define MAX_SIZE 100
typedef struct {
    int top;
    int data[MAX_SIZE];
} Stack;
void initStack(Stack *stack) {
    stack->top = -1;
}
int isEmpty(Stack *stack) {
    return stack->top == -1;
}
int isFull(Stack *stack) {
    return stack->top == MAX_SIZE - 1;
}
void push(Stack *stack, int value) {
    if (!isFull(stack)) {
        stack->data[++stack->top] = value;
    } else {
        printf("❗ 输入错误\n");
    }
}
int pop(Stack *stack) {
    if (!isEmpty(stack)) {
        return stack->data[stack->top--];
    } else {
        printf("❗ 输入错误\n");
        return -1; // Return an error value
    }
}
int peek(Stack *stack) {
    if (!isEmpty(stack)) {
        return stack->data[stack->top];
    } else {
        printf("❗ 输入错误\n");
        return -1; // Return an error value
    }
}
int precedence(char op) {
    switch (op) {
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        default:
            return 0;
    }
}
int applyOp(int a, int b, char op) {
    switch (op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': 
            if (b == 0) {
                printf("❗ 错误: 除数为0\n");
                return -1; // Return an error value
            }
            return a / b;
    }
    return 0;
}
int evaluate(char *expr) {
    Stack values, ops;
    initStack(&values);
    initStack(&ops);

    for (int i = 0; expr[i] != '\0'; i++) {
        if (isspace(expr[i])) {
            continue;
        } else if (isdigit(expr[i])) {
            int val = 0;
            while (i < strlen(expr) && isdigit(expr[i])) {
                val = (val * 10) + (expr[i] - '0');
                i++;
            }
            i--; // Correct the index after the loop increment
            push(&values, val);
        } else if (expr[i] == '(') {
            push(&ops, expr[i]);
        } else if (expr[i] == ')') {
            while (!isEmpty(&ops) && peek(&ops) != '(') {
                int val2 = pop(&values);
                int val1 = pop(&values);
                char op = pop(&ops);
                push(&values, applyOp(val1, val2, op));
            }
            if (!isEmpty(&ops) && peek(&ops) == '(') {
                pop(&ops); // Pop the '('
            } else {
                printf("❗ 错误: 括号不匹配\n");
                return -1; // Return an error value
            }
        } else if (expr[i] == '+' || expr[i] == '-' || expr[i] == '*' || expr[i] == '/') {
            while (!isEmpty(&ops) && precedence(peek(&ops)) >= precedence(expr[i])) {
                int val2 = pop(&values);
                int val1 = pop(&values);
                char op = pop(&ops);
                push(&values, applyOp(val1, val2, op));
            }
            push(&ops, expr[i]);
        }
    }

    while (!isEmpty(&ops)) {
        int val2 = pop(&values);
        int val1 = pop(&values);
        char op = pop(&ops);
        push(&values, applyOp(val1, val2, op));
    }

    return pop(&values);
}





//学生老师结构体
typedef struct student
{
    char name[128];
    char passwd[128];
    char sex[16];
    int age;
    // char talent[256];
}STUDENT;
typedef struct teacher
{
    char name[128];
    char passwd[128];
    char sex[16];
    int age;
    // char subject[128];
}TEACHER;
//留言结构体
typedef struct message
{
    char time[256];
    char name[128];
    char detail[1024];
}MESSAGE;



struct node
{
    void * data;//自己的数据
    struct node * pNext;//指向下一个节点的地址的指针
    struct node * pFront;//指向前一个节点地址的指针
};
typedef struct list
{
    struct node * pHead;//头节点
}LIST;
struct node * createNode(void * pData)
{
    struct node * p = malloc(sizeof(struct node));//定义一个节点
    p->data = pData;//数据等于x
    p->pNext = NULL;//下一个节点为空
    p->pFront = NULL;//上一个节点为空
    return p;
}


//函数声明
void createStudent(char id[16]);
void showStudentInfo(STUDENT* stu);
void createStudentData(LIST * pList);
void createTeacherData(LIST * pList);
void createMessageData(LIST * pList);


//非阻塞监听按键操作
int kbhit(void) {
    struct termios oldt, newt;
    int ch;
    int oldf;

    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

    ch = getchar();

    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    fcntl(STDIN_FILENO, F_SETFL, oldf);

    if (ch != EOF) {
        ungetc(ch, stdin);
        return 1;
    }

    return 0;
}

//创建并返回一个链表
LIST * createList()
{
    //分配一个链表的结构体，里面包含了链表的头指针和尾指针
    LIST * p = malloc(sizeof(LIST));
    p->pHead = createNode(NULL);//创建链表的头节点，注意这里不是链表的第一个数据节点
    return p;
}
//第一个参数使链表，里面有链表的头指针和尾指针
void addNode(LIST * pList, void * pData)
{
    //创建一个节点
    struct node * p = createNode(pData);

    if(pList->pHead->pNext == NULL)//说明当前是空链表
    {
        pList->pHead->pNext = p;//此时p就是链表的的第一个数据节点
        p->pFront = pList->pHead;//新节点的上一个是头节点
        pList->pHead->pFront = p;//头节点的上一个为新节点
        p->pNext = pList->pHead;//新节点的下一个为头节点
    }
    else
    {
        p->pNext = pList->pHead;//新节点的下一个为链表的头节点
        pList->pHead->pFront->pNext = p;//头节点的上一个节点的下一个为p（尾节点）
        p->pFront = pList->pHead->pFront;
        pList->pHead->pFront = p;
    }
}
void insert(LIST * pList , int pos , void * pData)
{
    //创建一个节点
    struct node * pNew = createNode(pData);
    struct node * p = pList->pHead->pNext;//p是链表的第一个数据节点

    //通过循环帮我们找到要插入的位置
    while (pos>0 && p!=pList->pHead)
    {
        pos--;
        p = p->pNext;
    }

    if(pos == 0 )
    {
        p->pFront->pNext = pNew;
        pNew->pFront = p->pFront;
        p->pFront = pNew;//p的上一个是pNew，p成为了pNew的下一个
        pNew->pNext = p;//新节点的下一个为p
    }
    else
    {
        printf("没有找到插入的位置\n");
    }
}
void del(LIST * pList, int pos)
{
    struct node * p = pList->pHead->pNext;//p是链表的第一个数据节点

    //通过循环帮我们找到要插入的位置
    while (pos>0 && p!=pList->pHead)
    {
        pos--;
        p = p->pNext;
    }

    if(pos == 0)
    {
        p->pFront->pNext = p->pNext;
        p->pNext->pFront = p->pFront;
        free(p);
    }
    else
    {
        printf("没有找到要删除的元素\n");
    }
}
//通过count函数获得链表一共有几个元素
int count(LIST * pList)
{
    int c = 0;
    //因为一开始头节点的前一个和后一个都是NULL,所以p不能等于NULL
    for (struct node * p = pList->pHead->pFront; p!=NULL&&p!=pList->pHead ; p=p->pFront)
    {
        c++;
    }
    return c;
}
//获得链表里面的数据
void * getData(LIST * pList , int pos)
{
    struct node * p = pList->pHead->pNext;//p是链表的第一个数据节点

    //通过循环帮我们找到要插入的位置
    while (pos>0 && p!=pList->pHead)
    {
        pos--;
        p = p->pNext;
    }

    if(pos == 0)
    {
        return p->data;//把节点的数据返回给用户
    }
    else
    {
        printf("你输入的位置不对\n");
        return NULL;
    }
}



//打印乘法表
void printMultiTable(STUDENT* stu){
    while (1) {
        if (kbhit()) {
            char ch = getchar();
            if (10 == ch)
            {
                break;
            }
        }
        else
        {
            system("clear");
            time_t t = time(0);
            struct tm* tm = localtime(&t);
            printf("【当前用户: 🧑%s】\n", stu->name);
            printf("                      🕒 %d-%02d-%02d   %02d:%02d:%02d\n", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
            printf("------------------------------九九乘法表🧮------------------------------\n");
            int i, j;
            for (i = 1; i <= 9; i++) {
                for (j = 1; j <= i; j++) {
                    printf("%dx%d=%-2d  ", j, i, i * j);
                }
                printf("\n");
            }
            printf("------------------------------------------------------------------------\n");
            printf("按回车键结束查看\n");
        }
        usleep(80000);
    }
}
//计算器
void calculator(STUDENT* stu){
    system("clear");
    time_t t = time(0);
    struct tm* tm = localtime(&t);
    printf("【当前用户: 🧑%s】\n\n", stu->name);
    printf("--------------计算器📱--------------\n");
    char expr[MAX_SIZE];
    printf("请输入需要计算的式子: ");
    fgets(expr, MAX_SIZE, stdin);
    expr[strcspn(expr, "\n")] = '\0';

    int result = evaluate(expr);
    if (result != -1) {
        printf("      🟢计算结果：👉 %d 👈\n", result);
    }
    printf("------------------------------------\n");
    printf("计算结束\n");
    printf("按回车键结束\n");
    char opr;
    scanf("%c", &opr);//按回车退出查看
}  
//猜数字
void guessNumGame(STUDENT* stu){
    while (1)
    {
        system("clear");
        int number, guess, attempts = 0;
        srand(time(0));
        number = rand() % 100 + 1;
        printf("【当前用户: 🧑%s】\n\n", stu->name);
        printf("----------🎰欢迎来到猜数字游戏🎰----------\n");
        printf("小华同学已经生成了一个1到100之间的随机数:🎲\n");
        do {
            printf("          😃请输入你的猜测：");
            scanf("%d", &guess);
            if (guess > 100) // 不按规则输入数字，说明不想玩，退出
            {
                printf("❌未按规则输入，退出游戏！\n");
                break;
            }
            
            attempts++;

            if (guess < number) {
                printf("☹ 太小了！再试一次\n");
            } else if (guess > number) {
                printf("☹ 太大了！再试一次\n");
            } else {
                printf("\n     😎恭喜你，猜对了！随机数为:%d🎲\n", number);
                printf("             你总共猜了 %d 次\n\n", attempts);
            }
        } while (guess != number);

        getchar();
        printf("--------按回车键结束游戏--------\n");
        char opr;
        scanf("%c", &opr);//按回车退出
        break;
    }
}
//课程表
void printTimetable(STUDENT* stu)
{
    while (1) {
        if (kbhit()) {
            char ch = getchar();
            if (10 == ch)
            {
                break;
            }
        }
        else
        {
            system("clear");
            time_t t = time(0);
            struct tm* tm = localtime(&t);
            printf("【当前用户: 🧑%s】\n\n", stu->name);
            printf("    🕒 %d-%02d-%02d   %02d:%02d:%02d\n", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
            printf("------------本周课程表📅------------\n");
            printf("     一     二    三    四    五   \n");
            printf("上  语文   英语  语文  英语  语文  \n");
            printf("午  数学   数学  音乐  政治  地理  \n");
            printf("\n");
            printf("下  英语   体育  化学  数学  历史  \n");
            printf("午  美术   物理  英语  生物  体育  \n");
            printf("------------------------------------\n");
            printf("按回车键结束查看\n");
        }
        usleep(80000);
    }
}

void printStudent(void * pData)
{
    printf("%-8s   %2s   %2d岁         特长:\n",((STUDENT*)pData)->name, ((STUDENT*)pData)->sex, ((STUDENT*)pData)->age);
}
void printTeacher(void * pData)
{
    printf("%-11s  %2s   %2d岁         学科:\n",((TEACHER*)pData)->name, ((TEACHER*)pData)->sex, ((TEACHER*)pData)->age);
}
void printMessage(void * pData){
    MESSAGE* p = (MESSAGE*)pData;
    printf(" [%s] 🧑%-8s:   %s\n",p->time, p->name, p->detail);
}

void printStudentPasswd(void * pData)
{
    STUDENT* p = (STUDENT*)pData;
    printf("🧑账号: %-8s   密码: %-12s  性别:%-s   年龄:%-d     特长:\n",p->name, p->passwd, p->sex, p->age);
}
void printTeacherPasswd(void * pData)
{
    TEACHER* p = (TEACHER*)pData;
    printf("👵账号: %-11s  密码: %-12s 性别:%-s   年龄:%-d     学科:\n",p->name, p->passwd, p->sex, p->age);
}

//打印整个链表
void printList(LIST * pList, void (*pFun)(void *))
{
    for (struct node * p = pList->pHead->pNext; p!=NULL ; p=p->pNext)
    {
        if(p == pList->pHead)
        {
            break;//头不能打印，直接跳过去
        }
        pFun(p->data);//把数据传给指定的函数
    }    
}

//超级管理员
void showAllInfo(){
    system("clear");
    while (1)
    {
        LIST * pList1 = createList();
        LIST * pList2 = createList();
        createStudentData(pList1);
        createTeacherData(pList2);
        printf("                       【👮超级管理员界面】\n");
        printf("-------------------------------------------------------------------------\n");
        printf("【----所有学生账号密码🧑----】          【----其他信息----】\n");
        printList(pList1, printStudentPasswd);
        printf("\n");
        printf("【----所有老师账号密码👵----】          【----其他信息----】\n");
        printList(pList2, printTeacherPasswd);
        printf("-------------------------------------------------------------------------\n");
        
        getchar();
        printf("按回车键结束查看");
        char opr;
        scanf("%c", &opr);//按回车退出查看
        break;
    }
}
void superAdmin(){
    printf("请输入超级管理员密码:");
    char passwd[128];
    scanf("%s", passwd);
    if (strcmp(passwd, "qiulovezai") == 0)
    {
        showAllInfo();
    }
    else
    {
        printf("❌密码错误!\n");
    }
}


//学生小工具
void showStudentTools(STUDENT* stu){
    while (1)
    {
        system("clear");
        printf("【当前用户: 🧑%s】\n\n", stu->name);
        printf("     请选择你的操作🔽\n\n");
        printf("     1【九九乘法表】📄  \n     2【计  算  器】📱  \n     3【猜数字游戏】🎰  \n     4【返      回】🔙\n");
        char opr[16];
        scanf("%s",opr);
        getchar();
        if(strcmp(opr,"1") == 0)
        {
            printMultiTable(stu);
        }
        else if(strcmp(opr,"2") == 0)
        {
            calculator(stu);
        }
        else if(strcmp(opr,"3") == 0)
        {
            guessNumGame(stu);
        }
        else if(strcmp(opr,"4") == 0)
        {
            break;
        }
    }
}
//学生留言
void leaveMessage(STUDENT* stu){
    while (1)
    {
        system("clear");
        printf("【当前用户: 🧑%s】\n\n", stu->name);
        printf("     请写下你想说的话💬\n\n");
        MESSAGE msg; //定义结构体接受输入的注册数据
        scanf("%s",msg.detail);
        strcpy(msg.name, stu->name);
        time_t t = time(0);
        struct tm* tm = localtime(&t);
        char str[256];
        sprintf(str,"%d-%02d-%02d %02d:%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
        strcpy(msg.time, str);
        
        //确认留言
        printf("\n☑ 确认留言?  [y/n]");
        char cfm[16];
        scanf("%s", cfm);
        if (strcmp(cfm,"y") == 0)
        {
            FILE* fp = fopen("message.txt", "ab+");

            fwrite(&msg, sizeof(msg), 1, fp);
            printf("✅学生:%s 留言成功! \n", msg.name);
            fclose(fp);
            sleep(1);
            break;
        }
        else
        {
            printf("❗取消留言\n");
            sleep(1);
            break;
        }
    }
}
//老师查看留言
void openMessage(TEACHER* tea){
    while (1)
    {
        if (kbhit()) {
            char ch = getchar();
            if (10 == ch)
            {
                break;
            }
        }
        else
        {
            system("clear");
            printf("\n");
            printf("【当前用户: 👵%s】\n\n", tea->name);
            LIST * pList = createList();
            createMessageData(pList);
            printf("-------------全部留言信息-------------\n\n");
            printList(pList, printMessage);
            printf("--------------------------------------\n");
            printf("按回车键结束查看\n");
        }
        usleep(50000);
    }
}

//从文件获取学生/老师/留言数据到链表中
void createStudentData(LIST * pList){
    FILE * pf = fopen("student.txt","rb");
    STUDENT * pST = malloc(sizeof(STUDENT));
    while(0 != fread(pST, sizeof(STUDENT), 1, pf))
    {
        addNode(pList, pST);//把从文件中读到的一个学生信息加入到链表中
        pST = malloc(sizeof(STUDENT));
    }
    free(pST);
    fclose(pf);
}
void createTeacherData(LIST * pList){
    FILE * pf = fopen("teacher.txt","rb");
    TEACHER * pST = malloc(sizeof(TEACHER));
    while(0 != fread(pST, sizeof(TEACHER), 1, pf))
    {
        addNode(pList, pST);//把从文件中读到的一个老师信息加入到链表中
        pST = malloc(sizeof(TEACHER));
    }
    free(pST);
    fclose(pf);
}
void createMessageData(LIST * pList){
    FILE * pf = fopen("message.txt","rb");
    MESSAGE * pST = malloc(sizeof(MESSAGE));
    while(0 != fread(pST, sizeof(MESSAGE), 1, pf))
    {
        addNode(pList, pST);//把从文件中读到的一个老师信息加入到链表中
        pST = malloc(sizeof(MESSAGE));
    }
    free(pST);
    fclose(pf);
}

//显示学生/老师信息
void showStudentInfo(STUDENT* stu){
    while (1)
    {
        system("clear");
        printf("\n");
        printf("【当前用户: 🧑%s】\n\n", stu->name);
        LIST * pList = createList();
        createStudentData(pList);
        printf("-------------全部学生信息-------------\n");
        printList(pList, printStudent);
        printf("--------------------------------------\n");
        printf("按回车键结束查看\n");
        char opr;
        scanf("%c", &opr);//按回车退出查看
        break;
    }
}
void showStudentInfoByTea(TEACHER* tea){
    while (1)
    {
        system("clear");
        printf("\n");
        printf("【当前用户: 👵%s】\n\n", tea->name);
        LIST * pList = createList();
        createStudentData(pList);
        printf("-------------全部学生信息-------------\n");
        printList(pList, printStudent);
        printf("--------------------------------------\n");
        printf("按回车键结束查看\n");
        char opr;
        scanf("%c", &opr);//按回车退出查看
        break;
    }
}
void showTeacherInfo(TEACHER* tea){
    while (1)
    {
        system("clear");
        printf("\n【当前用户: 👵%s】\n\n", tea->name);
        LIST * pList = createList();
        createTeacherData(pList);
        printf("-------------全部老师信息-------------\n");
        printList(pList, printTeacher);
        printf("--------------------------------------\n");
        printf("按回车键结束查看\n");
        char opr;
        scanf("%c", &opr);//按回车退出查看
        break;
    }
}

//老师-学生功能
void modifyStudent(){
    printf("请输入需要修改的学生姓名:\n");
    STUDENT stu;
    scanf("%s", stu.name);

    LIST * pList = createList();
    createStudentData(pList);
    int index = 0;
    bool findStu = false;//如果没找到该学生，定义一个变量，为0的话就不执行修改操作
    for (struct node* p = pList->pHead->pNext; p->data != NULL; p = p->pNext)
    {
        STUDENT* pData = ((STUDENT*)p->data);
        if(strcmp(stu.name, pData->name)  == 0)
        {
            findStu = true;
            break;
        }
        index++;//获取该学生在文件中的位置下标
    }
    if (findStu)
    {
        printf("请输入修改后的信息: \n用户名 密码 性别 年龄\n");
        STUDENT newStu;
        scanf("%s %s %s %d", newStu.name, newStu.passwd, newStu.sex, &newStu.age);

        //确认修改
        printf("确认修改?  [y/n]");
        char cfm[16];
        scanf("%s", cfm);
        if (strcmp(cfm,"y") == 0)
        {
            FILE* fp = fopen("student.txt", "rb+");
            fseek(fp, sizeof(STUDENT)*index, SEEK_SET);
            fwrite(&newStu, sizeof(STUDENT), 1, fp);
            fclose(fp);
            printf("✅温馨提示: 信息修改成功!\n");
            sleep(1);
        }
        else
        {
            printf("❗取消修改\n");
            sleep(1);
        }
    }
    else
    {
        printf("❌温馨提示: 未找到该学生!\n");
        sleep(1);
    }
}
void delStudent(){
    printf("请输入需要删除的学生姓名:\n");
    STUDENT stu;
    scanf("%s", stu.name);

    LIST * pList = createList();
    createStudentData(pList);
    int index = 0;
    bool findStu = false;//如果没找到该学生，定义一个变量，为0的话就不执行修改操作
    for (struct node* p = pList->pHead->pNext; p->data != NULL; p = p->pNext)
    {
        STUDENT* pData = ((STUDENT*)p->data);
        if(strcmp(stu.name, pData->name)  == 0)
        {
            findStu = true;
            break;
        }
        index++;//获取该学生在文件中的位置下标
    }
    if (findStu)
    {
        //确认删除
        printf("确认删除?  [y/n]");
        char cfm[16];
        scanf("%s", cfm);
        if (strcmp(cfm,"y") == 0)
        {
            //获取文件数据到链表中，删除对应下标位置的数据
            FILE* fp = fopen("student.txt", "rb+");
            STUDENT * pST = malloc(sizeof(STUDENT));
            LIST* pList1 = createList();
            while(0 != fread(pST, sizeof(STUDENT), 1, fp))
            {
                addNode(pList1, pST);
                pST = malloc(sizeof(STUDENT));
            }
            del(pList1, index);

            fclose(fp);
            //将删除后的链表重新写入文件
            fp = fopen("student.txt", "wb");
            struct node* p = pList1->pHead->pNext;

            while (p != pList1->pHead)
            {
                fwrite(p->data, sizeof(STUDENT), 1, fp);
                p = p->pNext;
            }
            fclose(fp);
            printf("✅温馨提示: 成功删除该学生!\n");
            sleep(1);
        }
        else
        {
            printf("❗取消删除\n");
            sleep(1);
        }
    }
    else
    {
        printf("❌温馨提示: 未找到该学生!\n");
        sleep(1);
    }
}

//老师-老师功能
void modifyTeacher(TEACHER* tea, bool * pchangeName){
    LIST * pList = createList();
    createTeacherData(pList);
    int index = 0;
    bool findTea = false;//如果没找到该老师时，确定位置下标
    for (struct node* p = pList->pHead->pNext; p->data != NULL; p = p->pNext)
    {
        TEACHER* pData = ((TEACHER*)p->data);
        if(strcmp(tea->name, pData->name)  == 0)
        {
            findTea = true;
            break;
        }
        index++;//获取该老师在文件中的位置下标
    }
    printf("请输入修改后的信息: \n用户名 密码 性别 年龄\n");
    TEACHER newTea;
    scanf("%s %s %s %d", newTea.name, newTea.passwd, newTea.sex, &newTea.age);

    //确认修改
    printf("确认修改?  [y/n]");
    char cfm[16];
    scanf("%s", cfm);
    if (strcmp(cfm,"y") == 0)
    {
        FILE* fp = fopen("teacher.txt", "rb+");
        fseek(fp, sizeof(TEACHER)*index, SEEK_SET);
        fwrite(&newTea, sizeof(TEACHER), 1, fp);
        fclose(fp);
        printf("✅温馨提示: 信息修改成功!\n");
        sleep(1);
        if (strcmp(newTea.name, tea->name) != 0)
        {
            *pchangeName = true;
        }
    }
    else
    {
        printf("❗取消修改\n");
        sleep(1);
    }
}
void delTeacher(TEACHER* tea){
    LIST * pList = createList();
    createTeacherData(pList);
    int index = 0;
    bool findStu = false;//如果没找到该学生，定义一个变量，为0的话就不执行修改操作
    for (struct node* p = pList->pHead->pNext; p->data != NULL; p = p->pNext)
    {
        TEACHER* pData = ((TEACHER*)p->data);
        if(strcmp(tea->name, pData->name)  == 0)
        {
            findStu = true;
            break;
        }
        index++;//获取该学生在文件中的位置下标
    }

        //获取文件数据到链表中，删除对应下标位置的数据
        FILE* fp = fopen("teacher.txt", "rb+");
        TEACHER * pST = malloc(sizeof(TEACHER));
        LIST* pList1 = createList();
        while(0 != fread(pST, sizeof(TEACHER), 1, fp))
        {
            addNode(pList1, pST);
            pST = malloc(sizeof(TEACHER));
        }
        del(pList1, index);

        fclose(fp);
        //将删除后的链表重新写入文件
        fp = fopen("teacher.txt", "wb");
        struct node* p = pList1->pHead->pNext;

        while (p != pList1->pHead)
        {
            fwrite(p->data, sizeof(TEACHER), 1, fp);
            p = p->pNext;
        }
        fclose(fp);
        printf("✅温馨提示: 成功注销! 返回登录界面\n");
        sleep(1);
}

//老师操作学生界面
void showStudentOperate(TEACHER* tea){
    while (1)
    {
        system("clear");
        printf("----------老师界面👵----------\n");
        printf("【当前用户: 👵%s】\n\n", tea->name);
        printf("     请选择你的操作🔽\n\n");
        printf("     1【查看学生信息】 \n     2【修改学生信息】 \n     3【  添加学生  】➕ \n     4【  删除学生  】➖ \n     5【  查看留言  】💬 \n     6【  返    回  】🔙\n");
        char opr[16];
        scanf("%s", opr);
        getchar();
        if (strcmp(opr, "1") == 0)
        {
            showStudentInfoByTea(tea);
        }
        if (strcmp(opr, "2") == 0)
        {
            modifyStudent();
        }
        if (strcmp(opr, "3") == 0)
        {
            createStudent("tea");
        }
        if (strcmp(opr, "4") == 0)
        {
            delStudent();
        }
        if (strcmp(opr, "5") == 0)
        {
            openMessage(tea);
        }
        if (strcmp(opr, "6") == 0)
        {
            break;
        }
    }
    
}
//老师操作老师界面
void showTeacherOperate(TEACHER* tea){
    while (1)
    {
        system("clear");
        printf("----------老师界面👵----------\n");
        printf("【当前用户: 👵%s】\n\n", tea->name);
        printf("     请选择你的操作🔽\n\n");
        printf("     1【查看全部老师信息】 \n     2【修改当前用户信息】 \n     3【  注销当前用户  】 \n     4【  返        回  】🔙\n");
        
        char opr[16];
        scanf("%s", opr);
        getchar();
        if (strcmp(opr, "1") == 0)
        {
            showTeacherInfo(tea);
        }
        if (strcmp(opr, "2") == 0)
        {
            bool changeName = false;
            bool *pchangeName = &changeName;
            modifyTeacher(tea, pchangeName);
            if (*pchangeName)
            {
                printf("❗用户名已修改，请重新登陆\n");
                sleep(2);
                break;
            }
        }
        if (strcmp(opr, "3") == 0)
        {
            printf("确认注销当前用户?  [y/n]");
            char cfm[16];
            scanf("%s", cfm);
            if (strcmp(cfm, "y") == 0)
            {
                delTeacher(tea);
                break;
            }
            else
            {
                printf("❗取消注销\n");
                sleep(1);
                break;
            }
            
        }
        if (strcmp(opr, "4") == 0)
        {
            break;
        }
    }
    
}

//主界面：老师/学生
void showStudentMenu(STUDENT* stu){
    printf("\n");
    printf("--------学生界面🧑--------\n");
    bool loop = true;
    while(loop)
    {
        system("clear");
        printf("【当前用户: 🧑%s】\n\n", stu->name);
        printf("     请选择你的操作🔽\n\n");
        printf("     1【查看学生信息】📄  \n     2【  课    表  】📅  \n     3【  小 工 具  】📐  \n     4【  留    言  】💬  \n     5【  退    出  】🔙\n");

        char opr[16];
        scanf("%s",opr);
        getchar();
        if(strcmp(opr,"1") == 0)
        {
            showStudentInfo(stu);
        }
        else if(strcmp(opr,"2") == 0)
        {
            printTimetable(stu);
        }
        else if(strcmp(opr,"3") == 0)
        {
            showStudentTools(stu);
        }
        else if(strcmp(opr,"4") == 0)
        {
            //留言
            leaveMessage(stu);
        }
        else if(strcmp(opr,"5") == 0)
        {
            loop = false;
        }          
    }
}
void showTeacherMenu(TEACHER* tea){
    while(1)
    {
        system("clear");
        printf("\n");
        printf("----------老师界面👵----------\n");
        printf("【当前用户: 👵%s】\n\n", tea->name);
        printf("     请选择你的操作🔽\n\n");
        printf("     1【学生相关操作】🧑  \n     2【老师相关操作】👵  \n     3【  退    出  】🔙\n");
        char opr[16];
        scanf("%s",opr);
        if(strcmp(opr,"1") == 0)
        {
            showStudentOperate(tea);
        }
        else if(strcmp(opr,"2") == 0)
        {
            showTeacherOperate(tea);
        }
        else if(strcmp(opr,"3") == 0)
        {
            break;
        }
        //随时检测用户名是否被注销 如果注销，立马break，回到登录界面
        LIST * pList = createList();
        createTeacherData(pList);
        bool loginSuccess = false;
        char retry[16];
        for (struct node* p = pList->pHead->pNext; p->data != NULL; p = p->pNext)
        {
            TEACHER* pData = ((TEACHER*)p->data);
            if(strcmp(tea->name, pData->name)  == 0)
            {
                loginSuccess = true;
            }
        }
        if (!loginSuccess)
        {
            break;
        }
    }
}

//登录界面
void loginStudent(){
    while (1)
    {
    system("clear");
        printf("\n");
        printf("🚩------欢迎进入学生管理系统------🚩\n\n");
        printf("     --------学生登录🧑--------\n");
        printf("     [请输入用户名和密码]\n");

        bool loginSuccess = false;
        char retry[16];

        STUDENT* stu = malloc(sizeof(STUDENT));
        printf("     🧑用户名:  ");scanf("%s", stu->name);
        printf("     🔑密  码:  " );scanf("%s", stu->passwd);

        LIST * pList = createList();
        createStudentData(pList);
        for (struct node* p = pList->pHead->pNext; p->data != NULL; p = p->pNext)
        {
            STUDENT* pData = ((STUDENT*)p->data);
            if(strcmp(stu->name, pData->name)  == 0 && strcmp(stu->passwd, pData->passwd) == 0)
            {
                loginSuccess = true;
            }
        }
        if (true == loginSuccess)
        {
            printf("✅登录成功\n");
            showStudentMenu(stu);
        }
        else
        {
            printf("❌用户名或密码错误，是否重新输入?  [y/n]\n");
            scanf("%s", retry);
            if (strcmp(retry, "y") == 0)
            {
                continue;
            }
            if (strcmp(retry, "n") == 0)
            {
                break;
            }
        }
        free(stu);
    }
}
void loginTeacher(){
    while (1)
    {
    system("clear");
        printf("\n");
        printf("🚩------欢迎进入学生管理系统------🚩\n\n");
        printf("     --------老师登录👵--------\n");
        printf("     [请输入用户名和密码]\n");

        LIST * pList = createList();
        createTeacherData(pList);
        bool loginSuccess = false;
        char retry[16];
        TEACHER* tea = malloc(sizeof(TEACHER));

        printf("     👵用户名:   ");scanf("%s", tea->name);
        printf("     🔑密  码:   " );scanf("%s", tea->passwd);
        for (struct node* p = pList->pHead->pNext; p->data != NULL; p = p->pNext)
        {
            TEACHER* pData = ((TEACHER*)p->data);
            if(strcmp(tea->name, pData->name)  == 0 && strcmp(tea->passwd, pData->passwd) == 0)
            {
                loginSuccess = true;
            }
        }
        if (true == loginSuccess)
        {
            printf("✅登录成功\n");
            getchar();
            showTeacherMenu(tea);
        }
        else
        {
            printf("❌用户名或密码错误，是否重新输入?  [y/n]\n");
            scanf("%s", retry);
            if (strcmp(retry, "y") == 0)
            {
                continue;
            }
            if (strcmp(retry, "n") == 0)
            {
                break;
            }
        }
        free(tea);
    }
}

//注册界面
void createStudent(char id[16]){
    system("clear");
    if (strcmp(id, "stu") == 0)
    {
        printf("\n");
        printf("🚩------欢迎进入学生管理系统------🚩\n\n");
        printf("--------学生注册🧑--------\n");
    }
    if (strcmp(id, "tea") == 0)
    {
        printf("--------添加学生👵--------\n");
    }
    
    printf("请依次输入: \n用户名  密码  性别  年龄\n");
    bool overlap = false;
    STUDENT stu;
    scanf("%s %s %s %d", stu.name, stu.passwd, stu.sex, &stu.age);

    //确认注册
    printf("确认注册?  [y/n]");
    char cfm[16];
    scanf("%s", cfm);
    if (strcmp(cfm,"y") == 0)
    {
        FILE* fp = fopen("student.txt", "ab+");
        //////////////////////////////  防止用户名重复注册
        LIST * pList = createList();
        STUDENT * pST = malloc(sizeof(STUDENT));
        while(0 != fread(pST, sizeof(STUDENT), 1, fp))
        {
            addNode(pList, pST);//把从文件中读到的一个学生信息加入到链表中
            pST = malloc(sizeof(STUDENT));
        }
        free(pST);

        for (struct node* p = pList->pHead->pNext; p->data != NULL; p = p->pNext)
        {
            if (strcmp(stu.name, ((STUDENT*)p->data)->name)  == 0)
            {
                overlap = true;
            }
        }
        if (overlap)
        {
            printf("❌该学生已存在!\n");
        }
        
        ///////////////////////////////
        else
        {
            fwrite(&stu, sizeof(stu), 1, fp);
            printf("✅学生:%s 注册成功! \n", stu.name);
        }
        fclose(fp);
        sleep(1);
    }
    else
    {
        printf("❗取消注册\n");
        sleep(1);
    }
}
void createTeacher(){
    system("clear");
    printf("--------老师注册👵--------\n");
    printf("请依次输入: \n用户名  密码  性别  年龄\n");
    bool overlap = false;
    TEACHER tea; //定义结构体接受输入的注册数据
    scanf("%s %s %s %d", tea.name, tea.passwd, tea.sex, &tea.age);
    //确认注册
    printf("确认注册?  [y/n]");
    char cfm[16];
    scanf("%s", cfm);
    if (strcmp(cfm,"y") == 0)
    {
        FILE* fp = fopen("teacher.txt", "ab+");
    //////////////////////////////  防止用户名重复注册
        LIST * pList = createList();
        TEACHER * pST = malloc(sizeof(TEACHER));
        while(0 != fread(pST, sizeof(TEACHER), 1, fp))
        {
            addNode(pList, pST);//把从文件中读到的一个学生信息加入到链表中
            pST = malloc(sizeof(TEACHER));
        }
        free(pST);

        for (struct node* p = pList->pHead->pNext; p->data != NULL; p = p->pNext)
        {
            if (strcmp(tea.name, ((TEACHER*)p->data)->name)  == 0)
            {
                overlap = true;
            }
        }
        if (overlap)
        {
            printf("❌该老师已存在!\n");
        }
        
    ///////////////////////////////
        else
        {
            fwrite(&tea, sizeof(tea), 1, fp);
            printf("✅老师:%s 注册成功! \n", tea.name);
        }
        fclose(fp);
        sleep(1);
    }
    else
    {
        printf("❗取消注册\n");
        sleep(1);
    }
}

//选择身份
void chooseLogin(){
    system("clear");
    printf("\n");
    printf("🚩------欢迎进入学生管理系统------🚩\n\n");
    printf("            请选择身份🔽\n\n");
    printf("           1【学生登录】🧑\n           2【老师登录】👵\n");
    char opr[16];
    scanf("%s", opr);
    if (strcmp(opr, "1") == 0)
    {
        loginStudent();
    }
    else if (strcmp(opr, "2") == 0)
    {
        loginTeacher();
    }
    else
    {
        printf("❌输入有误，返回上一级菜单\n");
        printf("\n");
        sleep(1);
    }
}
void chooseCreate(){
    system("clear");
    printf("\n");
    printf("🚩------欢迎进入学生管理系统------🚩\n\n");
    printf("            请选择身份🔽\n\n");
    printf("           1【学生注册】🧑\n           2【老师注册】👵\n");
    char opr[16];
    scanf("%s", opr);
    if (strcmp(opr, "1") == 0)
    {
        // system("clear");
        createStudent("stu");
    }
    else if (strcmp(opr, "2") == 0)
    {
        // system("clear");
        createTeacher();
    }
    else
    {
        printf("❌输入有误，返回上一级菜单\n");
        printf("\n");
        sleep(1);
    }
}


int main(int argc, char const *argv[])
{
    while (1)
    {
        system("clear");
        printf("\n");
        printf("🚩------欢迎进入学生管理系统------🚩\n");
        printf("\n           请选择你的操作🔽\n\n           1【  登录  】\n           2【  注册  】\n           3【退出系统】\n           4【忘记密码】🔐\n");
        char opr[16];
        scanf("%s", opr);
        if (strcmp(opr, "1") == 0)
        {
            chooseLogin();
        }
        if (strcmp(opr, "2") == 0)
        {
            chooseCreate();
        }
        if (strcmp(opr, "3") == 0)
        {
            // system("clear");
            printf("已退出系统\n");
            break;
        }
        if (strcmp(opr, "4") == 0)
        {
            superAdmin();
        }
    }
    
    
    return 0;
}
